package cn.geekyspace.scanhive.controller.fxml;

import cn.geekyspace.scanhive.pojo.entity.CleaningData;
import cn.geekyspace.scanhive.pojo.query.QueryData;
import cn.geekyspace.scanhive.service.CleaningDataService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Text;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

@Slf4j
@Component
@RequiredArgsConstructor
public class DataQueryController {
    @FXML
    public DatePicker scanDateStart;
    @FXML
    public DatePicker scanDateEnd;
    // 查询历史表格
    @FXML
    private TableView<CleaningData> tableView;
    @FXML
    private TableColumn<CleaningData, String> idColumn;
    @FXML
    private TableColumn<CleaningData, String> qrCodeColumn;
    @FXML
    private TableColumn<CleaningData, Integer> cleaningDurationColumn;
    @FXML
    private TableColumn<CleaningData, Double> cleaningTemperatureColumn;
    @FXML
    private TableColumn<CleaningData, Integer> rinsingDurationColumn;
    @FXML
    private TableColumn<CleaningData, Double> rinsingTemperatureColumn;
    @FXML
    private TableColumn<CleaningData, Integer> dryingDurationColumn;
    @FXML
    private TableColumn<CleaningData, Double> dryingTemperatureColumn;
    @FXML
    private TableColumn<CleaningData, String> qrCodeScanTimeColumn;
    @FXML
    private TableColumn<CleaningData, String> plcDataReturnTimeColumn;

    // 总条数
    @FXML
    private Text totalCount;

    // 当前页数 / 总页数
    @FXML
    private Label pageLabel;

    private int currentPage = 1;
    private int totalPage = 0;
    private static final int PAGE_SIZE = 15;

    // 注入
    private final CleaningDataService cleaningDataService;


    @FXML
    public void initialize() {
        // 设置表格列宽自动调整
        tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        // 监听 TableView 高度变化
        tableView.heightProperty().addListener((observable, oldValue, newValue) -> adjustRowHeight());


        // 动态生成列与属性的映射
        setupTableColumnMappings();
        // 设置 LocalDateTime 格式化
        qrCodeScanTimeColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getFormattedQrCodeScanTime()));
        plcDataReturnTimeColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getFormattedPlcDataReturnTime()));

        // 设置表格数据
        updatePageDisplay(new QueryData());
    }

    /**
     * 自动调整行高
     */
    private void adjustRowHeight() {
        Platform.runLater(() -> {
            double height = tableView.getHeight();
            double headerHeight = tableView.lookup(".column-header-background").getBoundsInLocal().getHeight();
            double availableHeight = height - headerHeight;
            double rowHeight = availableHeight / PAGE_SIZE - 0.5;
            tableView.setFixedCellSize(rowHeight);
        });
    }

    private void setupTableColumnMappings() {
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(FXML.class) && TableColumn.class.isAssignableFrom(field.getType())) {
                try {
                    field.setAccessible(true);
                    @SuppressWarnings("unchecked") TableColumn<CleaningData, ?> column = (TableColumn<CleaningData, ?>) field.get(this);
                    // 通过 fx:id 名称推导属性名
                    String propertyName = field.getName().replace("Column", "");
                    // 设置 CellValueFactory
                    column.setCellValueFactory(new PropertyValueFactory<>(propertyName));
                } catch (IllegalAccessException e) {
                    log.error("绑定 TableColumn '{}' 到属性失败。", field.getName(), e);
                }
            }
        }
    }

    /**
     * 上一页
     */
    @FXML
    public void prevPage(ActionEvent actionEvent) {
        if (currentPage > 1) {
            currentPage--;
            updatePageDisplay(new QueryData());
        }
    }

    /**
     * 下一页
     */
    @FXML
    public void nextPage(ActionEvent actionEvent) {
        if (currentPage < Math.max(0, totalPage)) {
            currentPage++;
            updatePageDisplay(new QueryData());
        }
    }

    /**
     * 更新页面显示
     */
    private void updatePageDisplay(QueryData query) {
        if (query == null) {
            query = new QueryData();
        }
        query.setCurrent(currentPage);
        query.setSize(PAGE_SIZE);

        Page<CleaningData> dataPage = cleaningDataService.cleaningDataPage(query);
        // 更新页面表格数据
        tableView.setItems(FXCollections.observableArrayList(dataPage.getRecords()));
        // 更新页面组件
        long total = dataPage.getTotal();
        totalCount.setText(String.valueOf(total));                   // 设置总条数
        totalPage = (int) Math.ceil((double) total / PAGE_SIZE);     // 总页数
        pageLabel.setText(String.format("%d / %d", currentPage, totalPage)); // 设置当前页数 / 总页数
    }

    /**
     * 搜索
     */
    @FXML
    public void search(MouseEvent mouseEvent) {
        if (mouseEvent.getSource() instanceof Button) {
            currentPage = 1;
            updatePageDisplay(new QueryData().setQrCodeScanTimeStart(scanDateStart.getValue()).setQrCodeScanTimeEnd(scanDateEnd.getValue()));
        }
    }

    /**
     * 重置
     */
    @FXML
    public void reset(MouseEvent mouseEvent) {
        if (mouseEvent.getSource() instanceof Button) {
            currentPage = 1;
            updatePageDisplay(new QueryData());
        }
    }

    /**
     * 转页
     */
    @FXML
    public void toPage(KeyEvent keyEvent) {
        if (keyEvent.getSource() instanceof TextField textField) {
            if (keyEvent.getCode() != KeyCode.ENTER) {
                return;
            }
            String text = textField.getText();
            if (text.matches("\\d+")) {
                int page = Integer.parseInt(text);
                if (page > 0 && page <= totalPage) {
                    currentPage = page;
                    updatePageDisplay(new QueryData());
                }
            }
        }
    }
}
